﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Collections.TreeCollections;
using System.Xml.Linq;

namespace FeatureModelCore.Configuration
{
    public enum RelationshipConfigureType
    {
        Manadory,
        Optional,
        Alternative,
        Or
    }
    public class ConfigRelationship : TreeNode
    {
        #region XML Symbol
        public readonly static string _XML_TYPE = "GroupRelationshipType";
        #endregion

        #region Properties
        public RelationshipConfigureType Type { get { return _type; } set { _type = value; } }
        public ConfigNode[] ChildrenNodes { get { return childrenNodes(); } }
        public ConfigNode ParentNode { get { return parentNode(); } }
        public ConfigRoot ParentRoot { get { return parentRoot(); } }
        #endregion

        #region Fields
        private RelationshipConfigureType _type;
        #endregion

        #region Constructor
        /// <summary>
        /// Constructor
        /// </summary>
        /// <param name="id"></param>
        public ConfigRelationship(TreeNodeIdentify id, RelationshipConfigureType type)
            : base(id)
        {
            _type = type;
        }
        #endregion
        /// <summary>
        /// Construct Group Relationship
        /// </summary>
        /// <param name="id"></param>
        /// <param name="args">args[0] is RelationshipConfigureType</param>
        /// <returns></returns>
        public static ConfigRelationship ConstructGroupRelationship(
            TreeNodeIdentify id, object[] args)
        {
            RelationshipConfigureType type = default(RelationshipConfigureType);
            if (args != null)
            {
                type = (RelationshipConfigureType)args[0];
            }
            return new ConfigRelationship(id, type);
        }

        #region XML Parser
        /// <summary>
        /// To Xml
        /// </summary>
        /// <returns></returns>
        public override XElement ToXElem()
        {
            XElement xelem = base.ToXElem();
            xelem.Add(new XAttribute(_XML_TYPE, _type.ToString()));

            return xelem;
        }
        /// <summary>
        /// Xml Parser
        /// </summary>
        /// <param name="xelem"></param>
        /// <returns></returns>
        public static void xmlParser(XElement xelem, TreeObject obj)
        {
            ConfigRelationship newGr = obj as ConfigRelationship;
            if(newGr == null)
            {
                throw new Exception("Type Error!");
            }

            string typeStr = xelem.Attribute(_XML_TYPE).Value;
            RelationshipConfigureType gType = (RelationshipConfigureType)
                Enum.Parse(typeof(RelationshipConfigureType)
                , typeStr, true);

            newGr._type = gType;
        }
        #endregion

        #region Get Tree Hierarchy Nodes
        /// <summary>
        /// get all children nodes
        /// </summary>
        /// <returns></returns>
        private ConfigNode[] childrenNodes()
        {
            List<ConfigNode> nodes = new List<ConfigNode>();
            foreach (INonRoot child in Children)
            {
                if (child is ConfigNode)
                {
                    nodes.Add((ConfigNode)child);
                }
            }
            return nodes.ToArray<ConfigNode>();
        }
        /// <summary>
        /// Get parent node
        /// </summary>
        /// <returns></returns>
        private ConfigNode parentNode()
        {
            ConfigNode node = this.Parent as ConfigNode;
            if (node == null)
            {
                throw new Exception("Parent Feature's Type is FeatureTreeRoot.");
            }
            return node;
        }
        /// <summary>
        /// Get parent root
        /// </summary>
        /// <returns></returns>
        private ConfigRoot parentRoot()
        {
            ConfigRoot root = this.Parent as ConfigRoot;
            if (root == null)
            {
                throw new Exception("Parent Feature's Type is FeatureTreeNode.");
            }
            return root;
        }
        #endregion

        public override string ToString()
        {
            return string.Format("{0},{1}"
                , base.ToString()
                , _type.ToString());
        }

        public override TreeRoot Parse2TreeRoot()
        {
            throw new NotImplementedException();
        }

        public override object Clone()
        {
            throw new NotImplementedException();
        }
    }
}
